drivers: st: mmc: improve error cases in send_cmd function
authorYann Gautier <[email protected]>
Fri, 30 Nov 2018 14:22:11 +0000 (15:22 +0100)
committerYann Gautier <[email protected]>
Tue, 4 Dec 2018 09:38:41 +0000 (10:38 +0100)
Signed-off-by: Yann Gautier <[email protected]>
drivers/st/mmc/stm32_sdmmc2.c

index 633a4250e199c10edb403f4aedc043eb502494fb..db5158156803b055812974a6f9977fb9e1967ad7 100644 (file)
@@ -97,7 +97,7 @@
 #define SDMMC_STAR_CMDSENT             BIT(7)
 #define SDMMC_STAR_DATAEND             BIT(8)
 #define SDMMC_STAR_DBCKEND             BIT(10)
-#define SDMMC_STAR_DPSMACT             BIT(11)
+#define SDMMC_STAR_DPSMACT             BIT(12)
 #define SDMMC_STAR_RXFIFOHF            BIT(15)
 #define SDMMC_STAR_RXFIFOE             BIT(19)
 #define SDMMC_STAR_IDMATE              BIT(27)
@@ -266,21 +266,22 @@ static int stm32_sdmmc2_send_cmd_req(struct mmc_cmd *cmd)
 
        mmio_write_32(base + SDMMC_CMDR, cmd_reg);
 
-       start = get_timer(0);
+       status = mmio_read_32(base + SDMMC_STAR);
 
-       do {
-               status = mmio_read_32(base + SDMMC_STAR);
+       start = get_timer(0);
 
+       while ((status & flags_cmd) == 0U) {
                if (get_timer(start) > TIMEOUT_10_MS) {
                        err = -ETIMEDOUT;
                        ERROR("%s: timeout 10ms (cmd = %d,status = %x)\n",
                              __func__, cmd->cmd_idx, status);
-                       break;
+                       goto err_exit;
                }
-       } while ((status & flags_cmd) == 0U);
 
-       if (((status & (SDMMC_STAR_CTIMEOUT | SDMMC_STAR_CCRCFAIL)) != 0U) &&
-           (err == 0)) {
+               status = mmio_read_32(base + SDMMC_STAR);
+       }
+
+       if ((status & (SDMMC_STAR_CTIMEOUT | SDMMC_STAR_CCRCFAIL)) != 0U) {
                if ((status & SDMMC_STAR_CTIMEOUT) != 0U) {
                        err = -ETIMEDOUT;
                        /*
@@ -300,9 +301,11 @@ static int stm32_sdmmc2_send_cmd_req(struct mmc_cmd *cmd)
                        ERROR("%s: CRCFAIL (cmd = %d,status = %x)\n",
                              __func__, cmd->cmd_idx, status);
                }
+
+               goto err_exit;
        }
 
-       if (((cmd_reg & SDMMC_CMDR_WAITRESP) != 0U) && (err == 0)) {
+       if ((cmd_reg & SDMMC_CMDR_WAITRESP) != 0U) {
                if ((cmd->cmd_idx == MMC_CMD(9)) &&
                    ((cmd_reg & SDMMC_CMDR_WAITRESP) == SDMMC_CMDR_WAITRESP)) {
                        /* Need to invert response to match CSD structure */
@@ -324,32 +327,26 @@ static int stm32_sdmmc2_send_cmd_req(struct mmc_cmd *cmd)
                }
        }
 
-       if ((flags_data == 0U) || (err != 0)) {
-               if (flags_data != 0U) {
-                       mmio_clrbits_32(base + SDMMC_CMDR, SDMMC_CMDR_CMDTRANS);
-               }
-
+       if (flags_data == 0U) {
                mmio_write_32(base + SDMMC_ICR, SDMMC_STATIC_FLAGS);
 
-               if ((err != 0) && (flags_data != 0U)) {
-                       return stm32_sdmmc2_stop_transfer();
-               }
-
-               return err;
+               return 0;
        }
 
-       start = get_timer(0);
+       status = mmio_read_32(base + SDMMC_STAR);
 
-       do {
-               status = mmio_read_32(base + SDMMC_STAR);
+       start = get_timer(0);
 
+       while ((status & flags_data) == 0U) {
                if (get_timer(start) > TIMEOUT_10_MS) {
                        ERROR("%s: timeout 10ms (cmd = %d,status = %x)\n",
                              __func__, cmd->cmd_idx, status);
                        err = -ETIMEDOUT;
-                       break;
+                       goto err_exit;
                }
-       } while ((status & flags_data) == 0U);
+
+               status = mmio_read_32(base + SDMMC_STAR);
+       };
 
        if ((status & (SDMMC_STAR_DTIMEOUT | SDMMC_STAR_DCRCFAIL |
                       SDMMC_STAR_TXUNDERR | SDMMC_STAR_RXOVERR |
@@ -359,11 +356,16 @@ static int stm32_sdmmc2_send_cmd_req(struct mmc_cmd *cmd)
                err = -EIO;
        }
 
+err_exit:
        mmio_write_32(base + SDMMC_ICR, SDMMC_STATIC_FLAGS);
        mmio_clrbits_32(base + SDMMC_CMDR, SDMMC_CMDR_CMDTRANS);
 
        if (err != 0) {
-               return stm32_sdmmc2_stop_transfer();
+               int ret_stop = stm32_sdmmc2_stop_transfer();
+
+               if (ret_stop != 0) {
+                       return ret_stop;
+               }
        }
 
        return err;